package hierarchy

import (
	"errors"
	"fmt"
	"gitee.com/g-qs/gin-vue-admin/server/global"
	"gitee.com/g-qs/gin-vue-admin/server/model/common/request"
	healthReq "gitee.com/g-qs/gin-vue-admin/server/model/health/request"
	"gitee.com/g-qs/gin-vue-admin/server/model/hierarchy"
	hierarchyReq "gitee.com/g-qs/gin-vue-admin/server/model/hierarchy/request"
	"gorm.io/gorm"
)

type FdArticleAudioService struct {
}

// CreateFdArticleAudio 创建FdArticleAudio记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleAudioService *FdArticleAudioService) CreateFdArticleAudio(fdArticleAudio *hierarchy.FdArticleAudio) (err error) {
	err = global.GVA_DB.Create(fdArticleAudio).Error
	return err
}

// DeleteFdArticleAudio 删除FdArticleAudio记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleAudioService *FdArticleAudioService) DeleteFdArticleAudio(fdArticleAudio hierarchy.FdArticleAudio) (err error) {
	var physique healthReq.PhysiqueArticle
	var solarTerms healthReq.FdJqArticle
	var efficacy healthReq.FdEfficacyArticle
	var disease healthReq.DiseaseArticle
	// 查询是否存在关联体质
	if !errors.Is(global.GVA_DB.Where("article_id = ? AND type = 'audio'", fdArticleAudio.ID).Preload("Physique").Preload("FdArticleAudio").First(&physique).Error, gorm.ErrRecordNotFound) {
		return errors.New("请先取消体质管理中【" + physique.Physique.Name + "】与【" + physique.FdArticleAudio.Title + "】的关联关系")
	}
	// 查询是否存在关联节气
	if !errors.Is(global.GVA_DB.Where("article_id = ? AND type = 'audio'", fdArticleAudio.ID).Preload("SolarTerms").Preload("FdArticleAudio").First(&solarTerms).Error, gorm.ErrRecordNotFound) {
		return errors.New("请先取消节气管理中【" + solarTerms.SolarTerms.JqName + "】与【" + solarTerms.FdArticleAudio.Title + "】的关联关系")
	}
	// 查询是否存在关联功效
	if !errors.Is(global.GVA_DB.Where("article_id = ? AND type = 'audio'", fdArticleAudio.ID).Preload("Efficacy").Preload("FdArticleAudio").First(&efficacy).Error, gorm.ErrRecordNotFound) {
		return errors.New("请先取消功效管理中【" + efficacy.Efficacy.Name + "】与【" + efficacy.FdArticleAudio.Title + "】的关联关系")
	}
	// 查询是否存在关联病症
	if !errors.Is(global.GVA_DB.Where("article_id = ? AND type = 'audio'", fdArticleAudio.ID).Preload("Disease", func(db *gorm.DB) *gorm.DB {
		return db.Preload("DiseaseList")
	}).Preload("FdArticleAudio").First(&disease).Error, gorm.ErrRecordNotFound) {
		return errors.New("请先取消病症管理中【" + disease.Disease.DiseaseList.Name + "】下的【" + disease.Disease.Name + "】与【" + disease.FdArticleAudio.Title + "】的关联关系")
	}
	err = global.GVA_DB.Delete(&fdArticleAudio).Error
	return err
}

// DeleteFdArticleAudioByIds 批量删除FdArticleAudio记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleAudioService *FdArticleAudioService) DeleteFdArticleAudioByIds(ids request.IdsReq) (err error) {
	var physique healthReq.PhysiqueArticle
	var solarTerms healthReq.FdJqArticle
	var efficacy healthReq.FdEfficacyArticle
	var disease healthReq.DiseaseArticle
	// 查询是否存在关联体质
	if !errors.Is(global.GVA_DB.Where("article_id in ? AND type = 'audio'", ids.Ids).Preload("Physique").Preload("FdArticleAudio").First(&physique).Error, gorm.ErrRecordNotFound) {
		return errors.New("请先取消体质管理中【" + physique.Physique.Name + "】与【" + physique.FdArticleAudio.Title + "】的关联关系")
	}
	// 查询是否存在关联节气
	if !errors.Is(global.GVA_DB.Where("article_id in ? AND type = 'audio'", ids.Ids).Preload("SolarTerms").Preload("FdArticleAudio").First(&solarTerms).Error, gorm.ErrRecordNotFound) {
		return errors.New("请先取消节气管理中【" + solarTerms.SolarTerms.JqName + "】与【" + solarTerms.FdArticleAudio.Title + "】的关联关系")
	}
	// 查询是否存在关联功效
	if !errors.Is(global.GVA_DB.Where("article_id in ? AND type = 'audio'", ids.Ids).Preload("Efficacy").Preload("FdArticleAudio").First(&efficacy).Error, gorm.ErrRecordNotFound) {
		return errors.New("请先取消功效管理中【" + efficacy.Efficacy.Name + "】与【" + efficacy.FdArticleAudio.Title + "】的关联关系")
	}
	// 查询是否存在关联病症
	if !errors.Is(global.GVA_DB.Where("article_id in ? AND type = 'audio'", ids.Ids).Preload("Disease", func(db *gorm.DB) *gorm.DB {
		return db.Preload("DiseaseList")
	}).Preload("FdArticleAudio").First(&disease).Error, gorm.ErrRecordNotFound) {
		return errors.New("请先取消病症管理中【" + disease.Disease.DiseaseList.Name + "】下的【" + disease.Disease.Name + "】与【" + disease.FdArticleAudio.Title + "】的关联关系")
	}
	err = global.GVA_DB.Delete(&[]hierarchy.FdArticleAudio{}, "id in ?", ids.Ids).Error
	return err
}

// UpdateFdArticleAudio 更新FdArticleAudio记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleAudioService *FdArticleAudioService) UpdateFdArticleAudio(fdArticleAudio hierarchy.FdArticleAudio) (err error) {
	//updateFields := map[string]interface{}{
	//	"title":          fdArticleAudio.Title,
	//	"briefly":        fdArticleAudio.Briefly,
	//	"cover":          fdArticleAudio.Cover,
	//	"video_link":     fdArticleAudio.VideoLink,
	//	"details":        fdArticleAudio.Details,
	//	"text":           fdArticleAudio.Text,
	//	"status":         fdArticleAudio.Status,
	//	"is_vip":         fdArticleAudio.IsVip,
	//	"level_one_id":   fdArticleAudio.LevelOneID,
	//	"level_two_id":   fdArticleAudio.LevelTwoID,
	//	"level_three_id": fdArticleAudio.LevelThreeID,
	//}
	//err = global.GVA_DB.Debug().Model(&hierarchy.ResArticleAudio{}).Where("id = ?", fdArticleAudio.ID).Updates(updateFields).Error
	err = global.GVA_DB.Save(&fdArticleAudio).Error
	return err
}

// GetFdArticleAudio 根据id获取FdArticleAudio记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleAudioService *FdArticleAudioService) GetFdArticleAudio(id uint, userID uint) (fdArticleAudio hierarchy.FdArticleAudio, err error) {
	var collect hierarchy.FdArticleCollect
	var like hierarchy.FdArticleLike
	coErr := global.GVA_DB.Where("fd_article_id = ? and user_id = ? and fd_article_type = ?", id, userID, "audio").First(&collect)
	liErr := global.GVA_DB.Where("fd_article_id = ? and user_id = ? and fd_article_type = ?", id, userID, "audio").First(&like)
	var articleAudio hierarchy.FdArticleAudio
	db := global.GVA_DB.Where("id = ?", id).First(&articleAudio)
	err = db.Error
	if coErr.Error != nil {
		articleAudio.IsCollect = false
	} else {
		articleAudio.IsCollect = true
	}
	if liErr.Error != nil {
		articleAudio.IsPraise = false
	} else {
		articleAudio.IsPraise = true
	}
	articleAudio.PV += 1
	db.Update("pv", articleAudio.PV)
	//praise, pv := fdArticleAudioService.GetPraiseAndPv(articleAudio.PV)
	fdArticleAudio.ID = articleAudio.ID
	fdArticleAudio.CreatedAt = articleAudio.CreatedAt
	fdArticleAudio.UpdatedAt = articleAudio.UpdatedAt
	fdArticleAudio.DeletedAt = articleAudio.DeletedAt
	fdArticleAudio.LevelOneID = articleAudio.LevelOneID
	fdArticleAudio.LevelOne = articleAudio.LevelOne
	fdArticleAudio.LevelTwoID = articleAudio.LevelTwoID
	fdArticleAudio.LevelTwo = articleAudio.LevelTwo
	fdArticleAudio.LevelThreeID = articleAudio.LevelThreeID
	fdArticleAudio.FdArticleLike = articleAudio.FdArticleLike
	fdArticleAudio.FdArticleCollect = articleAudio.FdArticleCollect
	fdArticleAudio.Title = articleAudio.Title
	fdArticleAudio.Briefly = articleAudio.Briefly
	fdArticleAudio.Cover = articleAudio.Cover
	fdArticleAudio.VideoLink = articleAudio.VideoLink
	fdArticleAudio.Text = articleAudio.Text
	fdArticleAudio.Details = articleAudio.Details
	fdArticleAudio.Status = articleAudio.Status
	fdArticleAudio.IsVip = articleAudio.IsVip
	fdArticleAudio.PraiseNum = articleAudio.PraiseNum
	fdArticleAudio.CollectNum = articleAudio.CollectNum
	fdArticleAudio.ForwardNum = articleAudio.ForwardNum
	fdArticleAudio.CommentNum = articleAudio.CommentNum
	fdArticleAudio.PV = articleAudio.PV
	fdArticleAudio.SearchNumber = articleAudio.SearchNumber
	fdArticleAudio.IsPraise = articleAudio.IsPraise
	fdArticleAudio.IsCollect = articleAudio.IsCollect
	return
}

func (fdArticleAudioService *FdArticleAudioService) GetPraiseAndPv(num int) (praise, pv string) {
	if num < 200 {
		// 点赞量 * 0.5 拼接“w+”
		likes := int(float64(num) * 0.5)
		praise = fmt.Sprintf("%dw+", likes)
		// 浏览量直接拼接“w+”
		pv = fmt.Sprintf("%dw+", num)
	} else {
		praise = "100w+"
		pv = fmt.Sprintf("%dw+", num)
	}
	return praise, pv
}

func (fdArticleAudioService *FdArticleAudioService) FdArticleLike(userID uint, id uint) (info hierarchy.FdArticleAudio, err error) {
	var fdArticleAudio hierarchy.FdArticleAudio
	tdb := global.GVA_DB.Where("id = ?", id).First(&fdArticleAudio)
	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		uidb := tx.Where("user_id = ? and fd_article_id = ? and fd_article_type = ?", userID, id, "audio").First(&hierarchy.FdArticleLike{})

		if errors.Is(uidb.Error, gorm.ErrRecordNotFound) {
			fdArticleAudio.PraiseNum += 1
			uidb = tx.Create(&hierarchy.FdArticleLike{
				UserID:        userID,
				FdArticleID:   id,
				FdArticleType: "audio",
			})
			fdArticleAudio.IsPraise = true
		} else {
			fdArticleAudio.PraiseNum -= 1
			uidb = tx.Delete(&hierarchy.FdArticleLike{}, "user_id = ? and fd_article_id = ? and fd_article_type = ?", userID, id, "audio")
			fdArticleAudio.IsPraise = false
		}
		return tdb.Update("praise_num", fdArticleAudio.PraiseNum).Error
	})
	//praise, pv := fdArticleAudioService.GetPraiseAndPv(fdArticleAudio.PV)
	info.ID = fdArticleAudio.ID
	info.CreatedAt = fdArticleAudio.CreatedAt
	info.UpdatedAt = fdArticleAudio.UpdatedAt
	info.DeletedAt = fdArticleAudio.DeletedAt
	info.LevelOneID = fdArticleAudio.LevelOneID
	info.LevelOne = fdArticleAudio.LevelOne
	info.LevelTwoID = fdArticleAudio.LevelTwoID
	info.LevelTwo = fdArticleAudio.LevelTwo
	info.LevelThreeID = fdArticleAudio.LevelThreeID
	info.FdArticleLike = fdArticleAudio.FdArticleLike
	info.FdArticleCollect = fdArticleAudio.FdArticleCollect
	info.Title = fdArticleAudio.Title
	info.Briefly = fdArticleAudio.Briefly
	info.Cover = fdArticleAudio.Cover
	info.VideoLink = fdArticleAudio.VideoLink
	info.Details = fdArticleAudio.Details
	info.Status = fdArticleAudio.Status
	info.IsVip = fdArticleAudio.IsVip
	info.PraiseNum = fdArticleAudio.PraiseNum
	info.CollectNum = fdArticleAudio.CollectNum
	info.ForwardNum = fdArticleAudio.ForwardNum
	info.CommentNum = fdArticleAudio.CommentNum
	info.SearchNumber = fdArticleAudio.SearchNumber
	info.PV = fdArticleAudio.PV
	info.IsPraise = fdArticleAudio.IsPraise
	info.IsCollect = fdArticleAudio.IsCollect
	return
}

func (fdArticleAudioService *FdArticleAudioService) FdArticleCollect(userID uint, id uint) (info hierarchy.FdArticleAudio, err error) {
	var fdArticleAudio hierarchy.FdArticleAudio
	tdb := global.GVA_DB.Where("id = ?", id).First(&fdArticleAudio)
	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		uidb := tx.Where("user_id = ? and fd_article_id = ? and fd_article_type = ?", userID, id, "audio").First(&hierarchy.FdArticleCollect{})

		if errors.Is(uidb.Error, gorm.ErrRecordNotFound) {
			fdArticleAudio.CollectNum += 1
			uidb = tx.Create(&hierarchy.FdArticleCollect{
				UserID:        userID,
				FdArticleID:   id,
				FdArticleType: "audio",
			})
			fdArticleAudio.IsCollect = true
		} else {
			fdArticleAudio.CollectNum -= 1
			uidb = tx.Delete(&hierarchy.FdArticleCollect{}, "user_id = ? and fd_article_id = ? and fd_article_type = ?", userID, id, "audio")
			fdArticleAudio.IsCollect = false
		}
		return tdb.Update("collect_num", fdArticleAudio.CollectNum).Error
	})
	//praise, pv := fdArticleAudioService.GetPraiseAndPv(fdArticleAudio.PV)
	info.ID = fdArticleAudio.ID
	info.CreatedAt = fdArticleAudio.CreatedAt
	info.UpdatedAt = fdArticleAudio.UpdatedAt
	info.DeletedAt = fdArticleAudio.DeletedAt
	info.LevelOneID = fdArticleAudio.LevelOneID
	info.LevelOne = fdArticleAudio.LevelOne
	info.LevelTwoID = fdArticleAudio.LevelTwoID
	info.LevelTwo = fdArticleAudio.LevelTwo
	info.LevelThreeID = fdArticleAudio.LevelThreeID
	info.FdArticleLike = fdArticleAudio.FdArticleLike
	info.FdArticleCollect = fdArticleAudio.FdArticleCollect
	info.Title = fdArticleAudio.Title
	info.Briefly = fdArticleAudio.Briefly
	info.Cover = fdArticleAudio.Cover
	info.VideoLink = fdArticleAudio.VideoLink
	info.Details = fdArticleAudio.Details
	info.Status = fdArticleAudio.Status
	info.IsVip = fdArticleAudio.IsVip
	info.PraiseNum = fdArticleAudio.PraiseNum
	info.CollectNum = fdArticleAudio.CollectNum
	info.ForwardNum = fdArticleAudio.ForwardNum
	info.CommentNum = fdArticleAudio.CommentNum
	info.SearchNumber = fdArticleAudio.SearchNumber
	info.PV = fdArticleAudio.PV
	info.IsPraise = fdArticleAudio.IsPraise
	info.IsCollect = fdArticleAudio.IsCollect
	return
}

// GetFdArticleAudioInfoList 分页获取FdArticleAudio记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleAudioService *FdArticleAudioService) GetFdArticleAudioInfoList(info hierarchyReq.FdArticleAudioSearch) (list []hierarchy.FdArticleAudio, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Table("fd_article_audio USE INDEX (deleted_at)")
	var fdArticleAudios []hierarchy.FdArticleAudio
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.LevelOneID != nil {
		db = db.Where("level_one_id = ?", info.LevelOneID)
	}
	if info.LevelTwoID != nil {
		db = db.Where("level_two_id = ?", info.LevelTwoID)
	}
	if info.LevelThreeID != nil {
		db = db.Where("level_three_id = ?", info.LevelThreeID)
	}
	if info.Title != "" {
		db = db.Where("title LIKE ?", "%"+info.Title+"%")
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}

	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}
	err = db.Find(&fdArticleAudios).Error
	return fdArticleAudios, total, err
}
